package com.app.service;

import com.app.model.main.*;
import com.app.model.response.ArticleOfFavorite;
import com.app.model.response.FavoriteResponseBody;
import com.app.model.response.RetCode;
import com.app.model.response.RetStatus;
import com.app.model.response.favorite.FavoritesInfo;
import com.app.model.response.favorite.FavoritesInfoWithFlag;
import com.app.model.util.CommonFlag;
import com.app.repository.interfaces.*;
import com.app.service.push.PushService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;

/**
 * Created by Lichaojie on 2017/4/7. It's a beautiful day.
 */
@Service
public class FavoriteService {
    private final Logger logger = Logger.getLogger(FavoriteService.class);

    @Autowired
    private ResponseService responseService;
    @Autowired
    private FavoriteMapper favoriteMapper;
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private UserInfoMapper userInfoMapper;
    @Autowired
    private ImageMapper imageMapper;
    @Autowired
    private CommentsOfArticleMapper commentsOfArticleMapper;
    @Autowired
    private ApprovalMapper approvalMapper;
    @Autowired
    private PushService pushService;
    @Autowired
    private FavoritesMapper favoritesMapper;
    @Autowired
    private FavoriteItemMapper favoriteItemMapper;

//    public RetStatus doFavorite( String parameter){
//        ObjectMapper objectMapper = new ObjectMapper();
//        Map paraMap = null;
//        try{
//            paraMap = objectMapper.readValue(parameter,Map.class);
//        }catch (IOException e){
//            e.printStackTrace();
//            return responseService.doResponse(204);
//        }
//
//        int objectId = (int)paraMap.get("objectId");
//        int userId = (int)paraMap.get("userId");
//        String time = (String)paraMap.get("time");
//        int type = (int)paraMap.get("type");
//
//        Favorite favorite = new Favorite();
//        favorite.setUserId((long)userId)
//                .setObjectId((long)objectId)
//                .setType((byte)type)
//                .setTime(time)
//                .setFlag((byte)1);
//
//        Favorite tFavorite = favoriteMapper.getFlagWithParam((long)userId,(long)objectId,(byte)type);
//        if(tFavorite == null){
//            if(favoriteMapper.insert(favorite) == 1){
//                pushService.pushNotification(favorite);
//                return responseService.doResponse(100);
//            }else{
//                return responseService.doResponse(200);
//            }
//        }else {
//            tFavorite.setFlag((byte)1);
//            if(favoriteMapper.updateByPrimaryKeySelective(tFavorite) == 1){
//                return responseService.doResponse(100);
//            }else {
//                return responseService.doResponse(200);
//            }
//        }
//
//
//    }

//    public RetStatus getMyFavoriteUpdate( String parameter){
//        ObjectMapper objectMapper = new ObjectMapper();
//        Map paraMap = null;
//        try{
//            paraMap = objectMapper.readValue(parameter,Map.class);
//        }catch (IOException e){
//            e.printStackTrace();
//            return responseService.doResponse(204);
//        }
//
//        int userId = (int)paraMap.get("userId");
//        int lastId = (int)paraMap.get("lastId");
//        int page = (int)paraMap.get("page");
//        int number = (int)paraMap.get("number");
//
//        List<FavoriteResponseBody> favoriteResponseBodyList = new ArrayList<>();
//
//        List<Favorite> favoriteList;
//        if(page == 0){//第一次进入此页面
//            favoriteList = favoriteMapper.getListOrderedByIdDESC(userId,favoriteMapper.getMaxId() + 1,page,number, CommonFlag.ARTICLE);
//        }else {
//            favoriteList = favoriteMapper.getListOrderedByIdASC(userId,lastId,page,number, CommonFlag.ARTICLE);
//        }
//
//        if(favoriteList != null && favoriteList.size() > 0){
//            for(Favorite favorite : favoriteList){
//                Article article = articleMapper.selectByPrimaryKey(favorite.getObjectId());
//                UserInfo userInfo = userInfoMapper.selectByPrimaryKey(article.getUserId());
//                ArticleOfFavorite articleOfFavorite = new ArticleOfFavorite();
//                articleOfFavorite.setUserId(userInfo.getId())
//                        .setNickName(userInfo.getNickName())
//                        .setAvator(imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin())
//                        .setLabel(userInfo.getLabel())
//                        .setCommentNum(commentsOfArticleMapper.getCommentsNumber(article.getId()))
//                        .setTime(favorite.getTime())
//                        .setTitle(article.getTitle())
//                        .setApprovalNum(approvalMapper.getApprovalNumber(article.getId(),CommonFlag.ARTICLE))
//                        .setContent(article.getContent())
//                        .setArticleId(article.getId());
//
//                FavoriteResponseBody favoriteResponseBody = new FavoriteResponseBody();
//                favoriteResponseBody
//                        .setType(CommonFlag.ARTICLE)
//                        .setObject(articleOfFavorite);
//
//                favoriteResponseBodyList.add(favoriteResponseBody);
//            }
//
//            RetStatus retStatus = new RetStatus();
//            retStatus.setCode(100)
//                    .setMessage(RetCode.getMessage(100))
//                    .setBody(favoriteResponseBodyList);
//            return retStatus;
//        }else {
//            return responseService.doResponse(216);
//        }
//    }

//    public RetStatus getMyFavoriteLoadMore( String parameter){
//        ObjectMapper objectMapper = new ObjectMapper();
//        Map paraMap = null;
//        try{
//            paraMap = objectMapper.readValue(parameter,Map.class);
//        }catch (IOException e){
//            e.printStackTrace();
//            return responseService.doResponse(204);
//        }
//
//        int userId = (int)paraMap.get("userId");
//        int lastId = (int)paraMap.get("lastId");
//        int page = (int)paraMap.get("page");
//        int number = (int)paraMap.get("number");
//
//        FavoriteResponseBody favoriteResponseBody = new FavoriteResponseBody();
//        List<ArticleOfFavorite> articleOfFavoriteList = new ArrayList<>();
//
//        List<Favorite> favoriteList;
//        favoriteList = favoriteMapper.getListOrderedByIdDESC(userId, lastId, page, number, CommonFlag.ARTICLE);
//        if(favoriteList != null && favoriteList.size() > 0){
//            for(Favorite favorite : favoriteList){
//                Article article = articleMapper.selectByPrimaryKey(favorite.getObjectId());
//                UserInfo userInfo = userInfoMapper.selectByPrimaryKey(article.getUserId());
//                ArticleOfFavorite articleOfFavorite = new ArticleOfFavorite();
//                articleOfFavorite.setUserId(userInfo.getId())
//                        .setNickName(userInfo.getNickName())
//                        .setAvator(imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin())
//                        .setLabel(userInfo.getLabel())
//                        .setCommentNum(commentsOfArticleMapper.getCommentsNumber(article.getId()))
//                        .setTime(favorite.getTime())
//                        .setTitle(article.getTitle())
//                        .setApprovalNum(approvalMapper.getApprovalNumber(article.getId(), CommonFlag.ARTICLE))
//                        .setContent(article.getContent())
//                        .setArticleId(article.getId());
//                articleOfFavoriteList.add(articleOfFavorite);
//
//            }
//            favoriteResponseBody.setType(CommonFlag.ARTICLE)
//                    .setObject(articleOfFavoriteList);
//
//            RetStatus retStatus = new RetStatus();
//            retStatus.setCode(100)
//                    .setMessage(RetCode.getMessage(100))
//                    .setBody(favoriteResponseBody);
//            return retStatus;
//        }else {
//            return responseService.doResponse(216);
//        }
//    }

    public RetStatus getFavorite(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int objectId = (int)paraMap.get("objectId");
        int userId = (int)paraMap.get("userId");
        int type = (int)paraMap.get("type");

        //Favorite favorite = favoriteMapper.getFlagWithParam((long)userId,(long)objectId,(byte)type);
        Map<String,Integer> map = new HashMap<>();
        List<Favorites> favoritesList = favoritesMapper.selectByUserId((long)userId);
        for (Favorites favorites : favoritesList){
            FavoriteItem favoriteItem = favoriteItemMapper.selectByFavoritesIdAndObjectId(favorites.getId(),objectId);
            if(favoriteItem != null && favoriteItem.getType() == type){
                map.put("flag", (int) favoriteItem.getFlag());
                RetStatus retStatus = new RetStatus();
                retStatus.setCode(100)
                        .setMessage(RetCode.getMessage(100))
                        .setBody(map);
                return retStatus;

            }
        }

        map.put("flag",0);
        RetStatus retStatus = new RetStatus();
        retStatus.setCode(100)
                .setMessage(RetCode.getMessage(100))
                .setBody(map);
        return retStatus;
    }

//    public RetStatus cancelFavorite(String parameter){
//        ObjectMapper objectMapper = new ObjectMapper();
//        Map paraMap = null;
//        try{
//            paraMap = objectMapper.readValue(parameter,Map.class);
//        }catch (IOException e){
//            e.printStackTrace();
//            return responseService.doResponse(204);
//        }
//
//        int objectId = (int)paraMap.get("objectId");
//        int userId = (int)paraMap.get("userId");
//        int type = (int)paraMap.get("type");
//
//        Favorite favorite = favoriteMapper.getFlagWithParam((long)userId,(long)objectId,(byte)type);
//
//        if(favorite != null){
//            favorite.setFlag((byte)0);
//            if(favoriteMapper.updateByPrimaryKeySelective(favorite) == 1){
//                return responseService.doResponse(100);
//            }
//        }
//
//        return responseService.doResponse(200);
//    }

    //==========================================================================================

    public RetStatus getFavoriteDirInfo(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        int postId = (int)paraMap.get("postId");

        List<Favorites> favoritesList = favoritesMapper.selectByUserId((long)userId);

        List<FavoritesInfoWithFlag> favoritesInfoWithFlagList = new ArrayList<>();

        if(favoritesList != null && favoritesList.size() > 0){
            Collections.reverse(favoritesList);

            for (Favorites favorites : favoritesList){
                List<FavoriteItem> favoriteItemList = favoriteItemMapper.selectByFavoritesId(favorites.getId());
                FavoritesInfoWithFlag favoritesInfoWithFlag = new FavoritesInfoWithFlag();
                favoritesInfoWithFlag.setFavoriteDir(favorites.getName())
                        .setFlag(favoriteItemMapper.selectByFavoritesIdAndObjectId(favorites.getId(),postId)==null?(byte)0:(byte)1)
                        .setArticleNum(favoriteItemList==null?0:favoriteItemList.size());
                favoritesInfoWithFlagList.add(favoritesInfoWithFlag);
            }
        }else {
            return responseService.doResponse(216);
        }

        RetStatus retStatus = new RetStatus();
        retStatus.setCode(100)
                .setMessage(RetCode.getMessage(100))
                .setBody(favoritesInfoWithFlagList);
        return retStatus;

    }

    public RetStatus newFavoritrDir(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        String name = (String)paraMap.get("favoriteDir");

        List<Favorites> favoritesList = favoritesMapper.selectByUserId((long) userId);
        if(favoritesList != null && favoritesList.size() > 20){
            return responseService.doResponse(302);//返回错误，表示收藏夹的数目过多
        }

        Favorites favorites = new Favorites();
        favorites.setUserId((long) userId)
                .setName(name)
                .setTime(Long.toString(System.currentTimeMillis()))
                .setFlag((byte) 1);

        if(favoritesMapper.insertSelective(favorites) == 1){
            return responseService.doResponse(100);
        }else {
            return responseService.doResponse(200);
        }
    }

    public RetStatus doFavorite(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        int postId = (int)paraMap.get("postId");
        String name = (String)paraMap.get("favoriteDir");

        Favorites favorites = favoritesMapper.selectByUserIdAndName((long) userId, name);
        if(favorites == null) return responseService.doResponse(200);

        FavoriteItem favoriteItem = new FavoriteItem();
        favoriteItem.setFavoritesId(favorites.getId())
                .setObjectId((long) postId)
                .setTime(Long.toString(System.currentTimeMillis()))
                .setFlag((byte) 1)
                .setType((byte) 0);

        FavoriteItem tFavoriteItem = favoriteItemMapper.selectByFavoritesIdAndObjectIdWithOutFlag(favorites.getId(), (long) postId);
        if(tFavoriteItem == null){
            if(favoriteItemMapper.insert(favoriteItem) == 1){
                pushService.pushNotification(favoriteItem);
                return responseService.doResponse(100);
            }else{
                return responseService.doResponse(200);
            }
        }else {
            tFavoriteItem.setFlag((byte)1);
            if(favoriteItemMapper.updateByPrimaryKeySelective(tFavoriteItem) == 1){
                return responseService.doResponse(100);
            }else {
                return responseService.doResponse(200);
            }
        }
    }

    public RetStatus getFavoriteDir(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");

        List<FavoritesInfo> favoritesInfoList = new ArrayList<>();

        List<Favorites> favoritesList = favoritesMapper.selectByUserId((long)userId);

        if(favoritesList != null && favoritesList.size() > 0){
            Collections.reverse(favoritesList);

            for (Favorites favorites : favoritesList){
                List<FavoriteItem> favoriteItemList = favoriteItemMapper.selectByFavoritesId(favorites.getId());

                FavoritesInfo favoritesInfo = new FavoritesInfo();
                favoritesInfo.setFavoriteDir(favorites.getName())
                        .setArticleNum(favoriteItemList==null?0:favoriteItemList.size());

                favoritesInfoList.add(favoritesInfo);
            }
        }else {
            return responseService.doResponse(216);
        }

        RetStatus retStatus = new RetStatus();
        retStatus.setCode(100)
                .setMessage(RetCode.getMessage(100))
                .setBody(favoritesInfoList);
        return retStatus;
    }

    public RetStatus getMyFavoriteUpdate(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        int lastId = (int)paraMap.get("lastId");
        int page = (int)paraMap.get("page");
        int number = (int)paraMap.get("number");
        String name = (String)paraMap.get("favoriteDir");

        Favorites favorites = favoritesMapper.selectByUserIdAndName((long)userId,name);
        if(favorites == null){
            return responseService.doResponse(332);
        }

        List<FavoriteResponseBody> favoriteResponseBodyList = new ArrayList<>();

        List<FavoriteItem> favoriteItemList;
        if(page == 0){//第一次进入此页面
            favoriteItemList = favoriteItemMapper.getListOrderedByIdDESC(favorites.getId(),(long)lastId,number,CommonFlag.ARTICLE);
        }else {
            favoriteItemList = favoriteItemMapper.getListOrderedByIdASC(favorites.getId(),(long)lastId,number,CommonFlag.ARTICLE);
        }

        if(favoriteItemList != null && favoriteItemList.size() > 0){
            for(FavoriteItem favoriteItem : favoriteItemList){
                Article article = articleMapper.selectByPrimaryKey(favoriteItem.getObjectId());
                UserInfo userInfo = userInfoMapper.selectByPrimaryKey(article.getUserId());
                ArticleOfFavorite articleOfFavorite = new ArticleOfFavorite();
                articleOfFavorite.setUserId(userInfo.getId())
                        .setNickName(userInfo.getNickName())
                        .setAvator(imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin())
                        .setLabel(userInfo.getLabel())
                        .setCommentNum(commentsOfArticleMapper.getCommentsNumber(article.getId()))
                        .setTime(favoriteItem.getTime())
                        .setTitle(article.getTitle())
                        .setApprovalNum(approvalMapper.getApprovalNumber(article.getId(),CommonFlag.ARTICLE))
                        .setContent(article.getContent())
                        .setArticleId(article.getId())
                        .setImage(article.getImage());

                FavoriteResponseBody favoriteResponseBody = new FavoriteResponseBody();
                favoriteResponseBody
                        .setType(CommonFlag.ARTICLE)
                        .setFavoriteId(favoriteItem.getId())
                        .setObject(articleOfFavorite);

                favoriteResponseBodyList.add(favoriteResponseBody);
            }

            RetStatus retStatus = new RetStatus();
            retStatus.setCode(100)
                    .setMessage(RetCode.getMessage(100))
                    .setBody(favoriteResponseBodyList);
            return retStatus;
        }else {
            return responseService.doResponse(216);
        }
    }

    public RetStatus getMyFavoriteLoadMore(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        int lastId = (int)paraMap.get("lastId");
        int page = (int)paraMap.get("page");
        int number = (int)paraMap.get("number");
        String name = (String)paraMap.get("favoriteDir");

        Favorites favorites = favoritesMapper.selectByUserIdAndName((long)userId,name);

        List<FavoriteResponseBody> favoriteResponseBodyList = new ArrayList<>();

        List<FavoriteItem> favoriteItemList;
        favoriteItemList = favoriteItemMapper.getListOrderedByIdDESC(favorites.getId(),(long)lastId,number,CommonFlag.ARTICLE);
        if(favoriteItemList != null && favoriteItemList.size() > 0){
            for(FavoriteItem favoriteItem : favoriteItemList){
                Article article = articleMapper.selectByPrimaryKey(favoriteItem.getObjectId());
                UserInfo userInfo = userInfoMapper.selectByPrimaryKey(article.getUserId());
                ArticleOfFavorite articleOfFavorite = new ArticleOfFavorite();
                articleOfFavorite.setUserId(userInfo.getId())
                        .setNickName(userInfo.getNickName())
                        .setAvator(imageMapper.selectByPrimaryKey(userInfo.getAvator()).getOrigin())
                        .setLabel(userInfo.getLabel())
                        .setCommentNum(commentsOfArticleMapper.getCommentsNumber(article.getId()))
                        .setTime(favoriteItem.getTime())
                        .setTitle(article.getTitle())
                        .setApprovalNum(approvalMapper.getApprovalNumber(article.getId(), CommonFlag.ARTICLE))
                        .setContent(article.getContent())
                        .setArticleId(article.getId())
                        .setImage(article.getImage());

                FavoriteResponseBody favoriteResponseBody = new FavoriteResponseBody();
                favoriteResponseBody
                        .setType(CommonFlag.ARTICLE)
                        .setFavoriteId(favoriteItem.getId())
                        .setObject(articleOfFavorite);

                favoriteResponseBodyList.add(favoriteResponseBody);
            }

            RetStatus retStatus = new RetStatus();
            retStatus.setCode(100)
                    .setMessage(RetCode.getMessage(100))
                    .setBody(favoriteResponseBodyList);
            return retStatus;
        }else {
            return responseService.doResponse(216);
        }
    }

    public RetStatus deleteFavoriteDir(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        String name = (String)paraMap.get("favoriteDir");

        Favorites favorites = favoritesMapper.selectByUserIdAndName((long)userId,name);
        if(favorites == null){
            return responseService.doResponse(304);
        }

        favorites.setFlag((byte)0);

        if(favoritesMapper.updateByPrimaryKeySelective(favorites) == 1){
            return responseService.doResponse(100);
        }else {
            return responseService.doResponse(200);
        }
    }

    public RetStatus emptyFavoriteDir(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        String name = (String)paraMap.get("favoriteDir");

        Favorites favorites = favoritesMapper.selectByUserIdAndName((long)userId,name);
        if(favorites == null){
            return responseService.doResponse(304);
        }

        List<FavoriteItem> favoriteItemList = favoriteItemMapper.selectByFavoritesId(favorites.getId());

        for (FavoriteItem favoriteItem : favoriteItemList){
            favoriteItem.setFlag((byte)0);
            if(favoriteItemMapper.updateByPrimaryKeySelective(favoriteItem) != 1){
                return responseService.doResponse(200);
            }
        }
        return responseService.doResponse(100);
    }

    public RetStatus cancelFavorite(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int objectId = (int)paraMap.get("articleId");
        int userId = (int)paraMap.get("userId");
        String name = (String)paraMap.get("favoriteDir");

        Favorites favorites = favoritesMapper.selectByUserIdAndName((long)userId,name);
        if(favorites == null) return responseService.doResponse(200);

        FavoriteItem favoriteItem = favoriteItemMapper.selectByFavoritesIdAndObjectId(favorites.getId(), (long) objectId);
        if(favoriteItem == null) return responseService.doResponse(200);

        favoriteItem.setFlag((byte)0);

        if(favoriteItemMapper.updateByPrimaryKey(favoriteItem) == 1){
            return responseService.doResponse(100);
        }else {
            return responseService.doResponse(200);
        }

    }

    public RetStatus editFavoriteDirName(String parameter){
        ObjectMapper objectMapper = new ObjectMapper();
        Map paraMap = null;
        try{
            paraMap = objectMapper.readValue(parameter,Map.class);
        }catch (IOException e){
            e.printStackTrace();
            return responseService.doResponse(204);
        }

        int userId = (int)paraMap.get("userId");
        String name1 = (String)paraMap.get("oldFavoriteDir");
        String name2 = (String)paraMap.get("newFavoriteDir");

        Favorites favorites = favoritesMapper.selectByUserIdAndName((long)userId,name1);
        if(favorites == null) return responseService.doResponse(200);

        favorites.setName(name2);

        if(favoritesMapper.updateByPrimaryKeySelective(favorites) == 1){
            return responseService.doResponse(100);
        }else {
            return responseService.doResponse(200);
        }

    }

}
